#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "nettle/gcm.h"
#define HASH_LENGTH 1024 * 1024 * 10
void str2uint(uint32_t length, uint8_t *dst, const char *src)
{
    uint32_t len = length / 2;
    uint32_t i;
    for (i = 0; i < length; ++i)
    {
        dst[i / 2] = 16 * ( src[i] < 'a' ? (src[i] - '0') : ((src[i] - 'a') + 10) );
        ++i;
        dst[i / 2] += ( src[i] < 'a' ? (src[i] - '0') : ((src[i] - 'a') + 10) );
    }
}


// nettle包中的MD5接口使用
int nettle_gcm_damo(unsigned int times, uint8_t *data)
{
	struct gcm_aes128_ctx ctx;
    const uint8_t z16[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

	const char iv[] =  "cafebabefacedbaddecaf888";
    const char key[] = "feffe9928665731c6d6a8f9467308308";
    const char auth[] = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
    const char clear[] = "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091";

    uint8_t key_uint[16];
    str2uint(strlen(key), key_uint, key);

    uint8_t z12[12];
    str2uint(24, z12, iv);

    uint8_t auth_uint[20];
    str2uint(strlen(auth), auth_uint, auth);

    uint8_t src[60];
    str2uint(strlen(clear), src, clear);


    uint8_t *dst = (uint8_t *)malloc(sizeof(uint8_t) * HASH_LENGTH);
    uint8_t digest[16];
	size_t length = strlen(auth);
    //printf("set key\n");
    gcm_aes128_set_key (&ctx, key_uint);
    //printf("set_iv\n");
    gcm_aes128_set_iv (&ctx, 12, z12);
    //printf("update\n");
    gcm_aes128_update (&ctx, sizeof(auth_uint), auth_uint);
    //printf("encrypt\n");
    gcm_aes128_encrypt (&ctx, HASH_LENGTH, dst, data);
    //printf("digest\n");
    gcm_aes128_digest (&ctx, sizeof(digest), digest);
	char hex_digest[sizeof(digest) * 2 + 1];

	if (times <= 5)
	{
		for (int i = 0; i < GCM_DIGEST_SIZE; i++)
		{
			sprintf(hex_digest + i * 2, "%02x", digest[i]);
		}
		printf("authtag: %s\n", hex_digest);
	}
    free(dst);
	return 0;
}